iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Mobile Development

Kotlin 全面啟動 系列 第 22

[Kotlin 全面啟動] SQLDelight

  • 分享至 

  • xImage
  •  

我們前幾天談了使用 Ktor 建立 http 連線獲取 remote 的資料,相信大家也會好奇 local 端的資訊存取 - 比如說 SQLite ,純 Kotlin 有沒有什麼解決方案呢?答案是有的,而且目前最推薦的竟然不是 JetBrains 官方出的,而是由開發 Retrofit 的 Sqare 所建立的另一個 open source project - SQLDelight。

SQLDelight 優秀的地方在於它可以解析你的 sql 語法,然後動態生成相關的程式碼,究竟它跟我們所熟悉的 Room 有什麼不一樣,讓我們繼續看下去。

Install

首先,我們需要 SQLDelight 的 dependency,值得注意的是他有動態生成 code 的功能,所以必須引入一個 plugin:

// root build.gradle.kts
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.squareup.sqldelight:gradle-plugin:1.5.3")
    }
}

再來就是一般 dependency 的部分,但因為各個平台的 SQLite 實作不同,以 KMM 來說就要分別引入 android、ios 等不同的 driver,同時也別忘了 apply 我們剛剛宣告的 plugin:

// shared module build.gradle.kts
plugins {
    id("com.squareup.sqldelight")
}

kotlin {
  sourceSets {
    val androidMain by getting {
      dependencies {
        implementation "com.squareup.sqldelight:android-driver:1.5.3"
      }
    }

    val iosMain by creating {
      dependencies {
        implementation "com.squareup.sqldelight:native-driver:1.5.3"
      }
    }
  }
}

Database

有了 dependency 之後,再來我們一起看看 SQLDelight 是怎麼自動生成我們所需要的程式碼的,首先需要定義一個 database,範例如下:

// shared module build.gradle.kts
sqldelight {
    database("MyDB") {
        packageName = "com.example.test"
    }
}

MyDB 是我們所定義的資料庫名字,而他的 package name 會是 com.example.test,compile 之後會發現 build 資料夾下多了一些檔案:

接下來我們在 commonMain 下建立一個 sqldelight 的資料夾,然後在這個資料夾下以一般 package 的結構建立資料夾,最後新增一個 Player.sq 的檔案如下:

CREATE TABLE hockeyPlayer (
  player_number INTEGER NOT NULL,
  full_name TEXT NOT NULL
);

CREATE INDEX hockeyPlayer_full_name ON hockeyPlayer(full_name);

INSERT INTO hockeyPlayer (player_number, full_name)
VALUES (15, 'Ryan Getzlaf');

就是一般的 SQL 語法對吧,但 build code 之後相對應的 Kotlin 程式就會在 build/generated/sqldelight/code 下自動產生囉!

我們打開有實作的 MyDBImpl 檔案看一下,會發現裡面有個 create function,其實就包含了我們剛剛在 Player.sq 所寫的 sql:

public override fun create(driver: SqlDriver): Unit {
  driver.execute(null, """
      |CREATE TABLE hockeyPlayer (
      |   player_number INTEGER NOT NULL,
      |   full_name TEXT NOT NULL
      | )
      """.trimMargin(), 0)
  driver.execute(null, "CREATE INDEX hockeyPlayer_full_name ON hockeyPlayer(full_name)", 0)
  driver.execute(null, """
      |INSERT INTO hockeyPlayer (player_number, full_name)
      | VALUES (15, 'Ryan Getzlaf')
      """.trimMargin(), 0)
}

這個 create function 其實會被具體的 driver class 呼叫,而我們一開始的 driver 都是個平台分開定義的,所以就會由各平台來建立這些 table 以及執行 sql 囉!

但除了一開始定義好 sql 語法以外,我們還有其他方法可以在 runtime 的時候操作 database 嗎?

敬請期待明天的內容囉~


上一篇
[Kotlin 全面啟動] Ktor Server
下一篇
[Kotlin 全面啟動] SQLDelight II
系列文
Kotlin 全面啟動 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言